﻿#if UNITY_EDITOR
using UnityEditor;
#endif
using System;
using System.Collections.Generic;
using System.Linq;
using Gp.Scripts.Core;
using Gp.Scripts.Core.Res;
using HighlightPlus;
using UnityEngine;
using Object = UnityEngine.Object;

namespace Helpers
{
    public static class ResHelper
    {
        private static readonly Dictionary<string, string[]> BundleNameCache = new();

        private static ResLoader _staticLoader;
        private static ResLoader StaticLoader => _staticLoader ??= ResLoader.Allocate();

        private static string[] GetBundleItemNames(string bundleName)
        {
            // bundleName = bundleName.ToLower();
            // var res = BundleNameCache.GetValueOrDefault(bundleName);
            // if (res == null && AssetBundleSettings.AssetBundleConfigFile is ResDatas resData)
            // {
            //     res = resData.AllAssetDataGroups
            //         .Where(x => x.key == bundleName)
            //         .SelectMany(x => x.AssetDatas)
            //         .Select(x => x.AssetName)
            //         .Where(x => x != bundleName)
            //         .ToArray();
            //
            //     StringBuilder sb = new StringBuilder("#AssetBundlesReference: ");
            //     foreach (var loadedNames in res)
            //     {
            //         sb.Append(loadedNames).Append('\n');
            //     }
            //
            //     BundleNameCache[bundleName] = res;
            //     Debug.Log(sb.ToString());
            // }


            // if (res == null)
            // {
                throw new Exception($"未找到对应资源，无效 AssetBundle 名称: {bundleName}");
            // }

            // return res;
        }


        public static void LoadByBundleSync(this ResLoader loader, string bundleName, Action<GameObject> processor)
        {
            var subObjs = GetBundleItemNames(bundleName);
            foreach (var subObjectName in subObjs)
            {
                processor(loader.LoadSync<GameObject>(subObjectName));
            }
        }


        public static IEnumerable<GameObject> LoadByBundleSync(this ResLoader loader, string bundleName)
        {
            var subObjs = GetBundleItemNames(bundleName);
            foreach (var subObjName in subObjs)
            {
                yield return loader.LoadSync<GameObject>(subObjName);
            }
        }


        /// <summary>
        /// 载入一个assetBundle中的所有gameObject。
        /// </summary>
        public static void LoadByBundleAsync(this ResLoader loader, string bundleName, Action<GameObject> processor)
        {
            var subObjs = GetBundleItemNames(bundleName);

            // foreach (var subObjectName in subObjs)
            // {
            //     loader.Add2Load(subObjectName, (b, res) =>
            //     {
            //         if (!b || res.Asset is not GameObject go) return;
            //         processor(go);
            //     });
            // }
            //
            // loader.LoadAsync();
        }


        public static HighlightProfile LoadHighlightProfile(string name)
        {
            return Resources.Load<HighlightProfile>($"HighlightProfile/{name}");
        }

        public static T LoadBasic<T>(string name) where T : Object
        {
            return StaticLoader.LoadSync<T>(ConstBundle.BASIC, name);
        }

        public static T LoadAssetInEditor<T>(string bundleName, string assetName) where T : Object
        {
            #if UNITY_EDITOR
            bundleName = bundleName.ToLower();
            var targetPaths = AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(bundleName, assetName);
            if (targetPaths.Length > 1)
            {
                Debug.LogError($"AB包内发现同名资源: bundleName-{bundleName}, assetName-{assetName}, at\n {string.Join('\n', targetPaths)}");
            }

            var targetPath = targetPaths
                .FirstOrDefault(x => typeof(T).IsAssignableFrom(AssetDatabase.GetMainAssetTypeAtPath(x)));
            if (string.IsNullOrEmpty(targetPath))
            {
                throw new Exception($"资源路径无效：{bundleName}, {assetName}");
            }

            return AssetDatabase.LoadAssetAtPath<T>(targetPath);
            #else
                throw new Exception("this Method should not be invoked");
            #endif
        }
    }
}